/*
 * Copyright (c) 2017-2020, Lindenis Tech. Ltd.
 * All rights reserved.
 *
 * File:
 *
 * Description:
 *
 * Author:
 *      xiaoshujun@lindeni.com
 *
 * Create Date:
 *      2020/11/18
 *
 * History:
 *
 */

#ifndef __MOTOR_CTRL_H__
#define __MOTOR_CTRL_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "osal_types.h"

typedef enum
{
    MOTOR_MSG_NULL                  = 0,
    MOTOR_MSG_RESET_COMPLETE        = 1,
    MOTOR_MSG_RUNNING               = 2,
    MOTOR_MSG_UPDATE_POS            = 3,
} MOTOR_MSG_e;

typedef enum _motor_direction_e
{
    MOTOR_DIRECTION_UP              = 0,
    MOTOR_DIRECTION_DOWN,
    MOTOR_DIRECTION_LEFT,
    MOTOR_DIRECTION_RIGHT,
} motor_direction_e;

typedef enum _limit_switch_set_e
{
    LIMIT_SWITCH_SET_NONE           = 0,
    LIMIT_SWITCH_SET_BEGIN,
    LIMIT_SWITCH_SET_END,
} limit_switch_set_e;

typedef enum _motor_dimension_e
{
    DIM_HORIZONTAL                  = 0,
    DIM_VERTICAL,
    DIM_CNT,
} motor_dimension_e;

#define MOTOR_CNT                   2

#define MOTOR_V_CC_UP               0
#define MOTOR_V_CC_DOWN             1
#define MOTOR_H_CC_LEFT             0
#define MOTOR_H_CC_RIGHT            1

typedef struct _motor_info_t
{
    uint8_t                 motor_dir;          // 0: horizontal, 1: vertical
    uint8_t                 motor_cc;           // clock wise directory
    uint8_t                 motor_speed;        // valid:[0, 100]
    int16_t                 around_steps;       // the steps of motor turn around
    int16_t                 action_steps;       // the steps of once action
    int16_t                 cur_pos;            // the current position of horizontal motor
    int16_t                 end_point;          // the steps form left to right
    uint8_t                 lmtsw_begin_id;     // the id of limit switch
    uint8_t                 lmtsw_end_id;       // the id of limit switch
} motor_info_t;

typedef struct _motorctrl_config_t
{
    comm_msg_cb             msg_cb;
    void *                  user;

    uint8_t                 motor_cnt;
    motor_info_t            motor[MOTOR_CNT];
} motorctrl_config_t;

/**
 * create a motor controller wrapper.
 *
 * @param
 * @return
 *    >0: the motor wrapper handle
 *    =0: failed
 */
_handle_t motorctrl_create();

/**
 * destory the motor controller wrapper.
 *
 * @param
 * @return
 */
void motorctrl_destory(_handle_t h_motor);

/**
 * initialize the motor wrapper if need.
 *
 * @param
 *    h_motor  [in]: the motor wrapper handle.
 *    p_config  [in]: the configuration.
 * @return
 *    =0: success
 *    <0: failed
 */
int motorctrl_init(_handle_t h_motor, motorctrl_config_t * p_config);

/**
 * deinitialize the motor wrapper.
 *
 * @param
 *    h_motor    [in]: the motor wrapper handle.
 * @return
 *    =0: success
 *    <0: failed
 */
int motorctrl_deinit(_handle_t h_motor);

/**
 * set motor runnig.
 *
 * @param
 *    h_motor   [in]: the motor wrapper handle.
 *    dir       [in]: the direction of motor turns.
 *    steps     [in]: the steps of motor turns.
 *    timeout_ms[in]: wait timeout the motor turn end, 0: do not wait.
 * @return
 *    =0: success
 *    <0: failed
 */
int motorctrl_run(_handle_t h_motor, motor_direction_e dir, int steps, int timeout_ms);
int motorctrl_stop(_handle_t h_motor, int id);
int motorctrl_stop_all(_handle_t h_motor);
int motorctrl_switch_stop(_handle_t h_motor, int switch_id);
int motorctrl_reset_boot(_handle_t h_motor);
int motorctrl_reset_boot_async(_handle_t h_motor);
int motorctrl_reset_center(_handle_t h_motor);
int motorctrl_reset_center_async(_handle_t h_motor);
int motorctrl_update_position(_handle_t h_motor, int motor_id, int steps);

#ifdef __cplusplus
}
#endif

#endif  // __MOTOR_CTRL_H__


